package controller

import (
	"backEnd/common"
	"backEnd/dto"
	"backEnd/model"
	"backEnd/util"
	"fmt"
	"net/http"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/jinzhu/gorm"
)

func Publish(ctx *gin.Context) {
	var (
		middleUser, _   = ctx.Get("user")
		sellerId        = middleUser.(model.User).ID
		DB              = common.GetDB()
		requestProduct  = model.Product{}
		ProductCoverImg = make([]model.ProductCoverImg, 0)
	)

	if err := ctx.ShouldBindJSON(&requestProduct); err != nil {
		fmt.Print(requestProduct)
		ctx.JSON(400, gin.H{
			"msg": "商品信息接收失败",
			"err": err.Error(),
		})
		return
	}

	if len(requestProduct.ProductCoverImg) != 0 {
		//获取参数
		ProductCoverImg = requestProduct.ProductCoverImg

		for i, ProductCoverImgFile := range ProductCoverImg {
			ImgUrl := util.GenerateImgUrl(ProductCoverImgFile.ProductCoverImg)
			ProductCoverImg[i].ProductCoverImg = ImgUrl
		}
	}

	//创建商品
	newProduct := model.Product{
		ProductName:     requestProduct.ProductName,
		ProductPrice:    requestProduct.ProductPrice,
		SellerId:        sellerId,
		ProductZone:     requestProduct.ProductZone,
		ProductCoverImg: ProductCoverImg,
		Detail: model.ProductDetail{
			Timestamp:    time.Now().Unix(),
			AliveTime:    requestProduct.Detail.AliveTime,
			ExpiratedAt:  time.Unix(requestProduct.Detail.AliveTime+time.Now().Unix(), 0).In(time.Local), //到期时间
			SellStatus:   0,
			Connection:   requestProduct.Detail.Connection,
			ProductIntro: requestProduct.Detail.ProductIntro,
		},
	}

	fmt.Print("发布了新商品:", newProduct, "\n")
	if err := DB.Create(&newProduct).Error; err != nil {
		ctx.JSON(500, gin.H{
			"msg": "保存新商品失败",
			"err": err.Error(),
		})
	}

	//修改seller的“发布过商品数量”字段
	if err := DB.Model(&model.User{}).Where("id = ?", sellerId).UpdateColumn("published_items_count", gorm.Expr("published_items_count + ?", 1)).Error; err != nil {
		ctx.JSON(500, gin.H{
			"msg": "数据库内部错误",
			"err": err.Error(),
		})
	}

	//返回结果
	ctx.JSON(201, gin.H{
		"msg": "发布成功",
	})
}

func Detail(ctx *gin.Context) {
	var (
		Product         = model.Product{}
		ProductDetail   = model.ProductDetail{}
		ProductCoverImg = []model.ProductCoverImg{}
		Seller          = &model.User{}
		DB              = common.GetDB()
	)

	if err := ctx.ShouldBindJSON(&Product); err != nil {
		fmt.Print(Product)
		ctx.JSON(400, gin.H{
			"msg": "商品信息接收失败",
			"err": err.Error(),
		})
		return
	}

	if DB.Where("product_id = ?", Product.ProductId).Find(&Product).RecordNotFound() {
		ctx.JSON(404, gin.H{
			"msg": "商品不存在",
		})
		return
	}
	if DB.Where("product_id = ?", Product.ProductId).Find(&ProductCoverImg).RecordNotFound() {
		ctx.JSON(404, gin.H{
			"msg": "图片查询失败",
		})
		return
	}
	if DB.Where("id = ?", Product.ProductId).Find(&ProductDetail).RecordNotFound() {
		ctx.JSON(404, gin.H{
			"msg": "商品详情获取失败",
		})
		return
	}

	if len(ProductCoverImg) == 0 {
		ProductCoverImg = make([]model.ProductCoverImg, 1)
	}

	Product.ProductCoverImg = ProductCoverImg
	Product.Detail = ProductDetail

	Seller = dto.GetInternalUserById(Product.SellerId)
	Seller.Password = ""
	ctx.JSON(200, gin.H{
		"product": Product,
		"seller":  Seller,
	})
}

func UpdateProduct(ctx *gin.Context) {
	var (
		updatedProduct model.Product
		DB             = common.GetDB()
		seller, _      = ctx.Get("user")
	)

	// 从请求体中获取更新的商品信息
	if err := ctx.ShouldBindJSON(&updatedProduct); err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{
			"msg":   "参数错误",
			"error": err.Error(),
		})
		return
	}

	// 从数据库中查询商品信息
	if DB.Model(&model.Product{}).Where("seller_id = ? AND product_id = ?", seller.(model.User).ID, updatedProduct.ProductId).RecordNotFound() {
		ctx.JSON(500, gin.H{
			"msg": "该商品不存在或不由您发布",
		})
		return
	}

	//修改商品
	newProduct := model.Product{
		ProductId:       updatedProduct.ProductId,
		ProductName:     updatedProduct.ProductName,
		ProductPrice:    updatedProduct.ProductPrice,
		SellerId:        seller.(model.User).ID,
		ProductZone:     updatedProduct.ProductZone,
		ProductCoverImg: updatedProduct.ProductCoverImg,
		Detail: model.ProductDetail{
			ID:           updatedProduct.ProductId,
			Timestamp:    time.Now().Unix(),
			AliveTime:    updatedProduct.Detail.AliveTime,
			ExpiratedAt:  time.Unix(updatedProduct.Detail.AliveTime+time.Now().Unix(), 0).In(time.Local), //到期时间
			SellStatus:   0,
			Connection:   updatedProduct.Detail.Connection,
			ProductIntro: updatedProduct.Detail.ProductIntro,
		},
	}

	if err := DB.Model(&model.ProductCoverImg{}).Where("product_id = ?", updatedProduct.ProductId).Delete(&model.ProductCoverImg{}).Error; err != nil {
		ctx.JSON(500, gin.H{
			"msg": "保存商品失败",
			"err": err.Error(),
		})
	}

	fmt.Print("\n修改了商品:", newProduct, "\n")
	if err := DB.Save(&newProduct).Error; err != nil {
		ctx.JSON(500, gin.H{
			"msg": "保存商品失败",
			"err": err.Error(),
		})
	}
	ctx.JSON(http.StatusOK, gin.H{
		"msg": "商品信息更新成功",
	})
}

func Delist(ctx *gin.Context) {
	var (
		DB                = common.GetDB()
		user, _           = ctx.Get("user")
		requestProductIds = make(map[string][]interface{})
	)
	if err := ctx.ShouldBindJSON(&requestProductIds); err != nil {
		fmt.Print("错误,接收到的数据为：", requestProductIds)
		ctx.JSON(400, gin.H{
			"msg": "商品信息接收失败",
			"err": err.Error(),
		})
		return
	}

	productIDs := make([]int, len(requestProductIds["product_id"]))

	if err := DB.Model(&model.Product{}).Select("product_id").Where("product_id IN (?) AND seller_id = ?", requestProductIds["product_id"], user.(model.User).ID).Pluck("product_id", &productIDs).Error; err != nil {
		ctx.JSON(500, gin.H{
			"msg": "查找商品失败",
			"err": err,
		})
	} else if len(productIDs) == 0 {
		ctx.JSON(500, gin.H{
			"msg": "未查找到该商品",
			"err": err,
		})
		return
	}

	if err := DB.Model(&model.ProductDetail{}).Where("id IN (?)", productIDs).Update("sell_status", 1).Update("alive_time", 0).Error; err != nil {
		ctx.JSON(500, gin.H{
			"msg": "更新商品状态失败",
			"err": err,
		})
	}

	ctx.JSON(200, gin.H{
		"msg": "更新成功",
	})
}

func Report(ctx *gin.Context) {
	DB := common.GetDB()
	user, _ := ctx.Get("user")
	var reportRecord model.ReportRecord
	var existingRecord model.ReportRecord
	var ReportReasons []string
	var Reporters []uint //添加举报人的slice

	//接收举报记录,将记录中的string转化
	if err := ctx.ShouldBindJSON(&reportRecord); err != nil {
		ctx.JSON(500, gin.H{
			"msg": "举报接收失败",
			"err": err.Error(),
		})
		return
	}

	// 如果被举报商品已存在，则将其“被举报次数”字段加一，并更新数据库中的记录
	if err := DB.Where("product_id = ?", reportRecord.ProductId).First(&existingRecord).Error; err == nil {

		//将已存在商品的被举报理由和举报人从json转为[]string
		ReportReasons = util.FromJSON(existingRecord.ReportReasons)
		Reporters = util.FromJSONUint(existingRecord.ReportersId)
		existingRecord.TimesReported++

		//添加被举报理由记录和举报人记录
		ReportReasons = append(ReportReasons, reportRecord.ReportReasons)
		Reporters = append(Reporters, user.(model.User).ID)

		//重新转回json并更新记录
		existingRecord.ReportReasons = util.ToJSON(ReportReasons)
		existingRecord.ReportersId = util.ToJSONUint(Reporters)
		if err := DB.Save(&existingRecord).Error; err != nil {
			ctx.JSON(500, gin.H{
				"msg": "更新记录失败",
				"err": err.Error(),
			})
			return
		}
		ctx.JSON(200, gin.H{"msg": "举报记录添加成功，请等待审核"})
		return
	}

	// 如果不存在，则新建一条记录
	// 将“被举报次数”字段设为1,“举报人”字段为当前用户，将被举报理由转为[]string并存储
	reportRecord.TimesReported = 1
	Reporters = append(Reporters, user.(model.User).ID)
	reportRecord.ReportersId = util.ToJSONUint(Reporters)
	ReportReasons = append(ReportReasons, reportRecord.ReportReasons)
	reportRecord.ReportReasons = util.ToJSON(ReportReasons)

	if err := DB.Create(&reportRecord).Error; err != nil {
		ctx.JSON(500, gin.H{
			"msg": "举报记录创建失败",
			"err": err.Error(),
		})
		return
	}

	ctx.JSON(201, gin.H{"msg": "举报记录创建成功，请等待审核"})
}
